#pragma once
#include "../toLua++/tolua++.h"
#include "../../lua-5.1.5/src/lua.h"
#include "LuaVM.h"


#ifndef SAFE_DELETE
#define SAFE_DELETE(p)       { if (p) { delete (p);     (p)=NULL; } }
#endif // !SAFE_DELETE

#ifndef SAFE_RELEASE
#define SAFE_RELEASE(p)      { if (p) { (p)->Release(); (p)=NULL; } }
#endif // !SAFE_RELEASE

#define LOG_PROCESS_ERROR(Condition)	if(!(Condition)){ goto Exit0;}

//#define KLUA_L					 g_GetLuaVM()->LuaState()
#define KLUA_CALL_BEGIN			 g_GetLuaVM()->CallFunctionBegin
#define KLUA_CALL_END			 g_GetLuaVM()->CallFunctionEnd
//#define KLUA_GET_GLOBAL_FUNC     g_GetLuaVM()->GetGlobalFunction
//#define KLUA_GET_GLOBAL_VALUE    g_GetLuaVM()->GetGlobalValue
//#define KLUA_GET_LUA_OBJ         g_GetLuaVM()->GetLuaObject

//#define LuaCall0(LuaState,Func)             \
//	if(Func.PushFunction()){nRetCode = Func.CallFunction(0,1);} else nRetCode = FALSE;
//
//#define LuaCall1(LuaState,Func,v0)\
//	if(Func.PushFunction()){push(LuaState,v0);nRetCode = Func.CallFunction(1,1);} else nRetCode = FALSE;
//
//#define LuaCall2(LuaState,Func,v0,v1)\
//	if(Func.PushFunction()){push(LuaState,v0);push(LuaState,v1);nRetCode = Func.CallFunction(2,1);}else nRetCode = FALSE;
//
//#define LuaCall3(LuaState,Func,v0,v1,v2)\
//	if(Func.PushFunction()){push(LuaState,v0);push(LuaState,v1);push(LuaState,v2);nRetCode = Func.CallFunction(3,1);} else nRetCode = FALSE;
//
//#define LuaCall4(LuaState,Func,v0,v1,v2,v3)\
//	if(Func.PushFunction()){push(LuaState,v0);push(LuaState,v1);push(LuaState,v2);push(LuaState,v3);nRetCode = Func.CallFunction(4,1);} else nRetCode = FALSE;
//
//#define LuaCall5(LuaState,Func,v0,v1,v2,v3,v4)\
//	if(Func.PushFunction()){push(LuaState,v0);push(LuaState,v1);push(LuaState,v2);push(LuaState,v3);push(LuaState,v4);nRetCode = Func.CallFunction(5,1);} else nRetCode = FALSE;
//

//#define LuaSimpleCall0(LuaState,Func)             \
//	do {                                             \
//		int nTopIndex = 0; \
//		KLUA_CALL_BEGIN(&nTopIndex);\
//		if(g_GetLuaVM()->PushFunction(Func)){}
//		if(Func.PushFunction())
//			{nRetCode = Func.CallFunction(0,1);} 
//		else nRetCode = FALSE; \
//		KLUA_CALL_END(nTopIndex); \
//	} while(0)

#define   LuaSimpleCall0(LuaState,pcsFunc)\
	do{                                 \
		int nTopIndex = 0; \
		KLUA_CALL_BEGIN(&nTopIndex);\
		if(g_GetLuaVM()->PushFunction(pcsFunc)){g_GetLuaVM()->CallFunction(0,0);} \
		KLUA_CALL_END(nTopIndex); \
	}while(0)


//bool LuaSimpleCall0(lua_State* L, const char* pcsFunc)
//{
//	int nTopIndex = 0;
//	bool ret = false;
//	KLUA_CALL_BEGIN(&nTopIndex); 
//	if (g_GetLuaVM()->PushFunction(pcsFunc))
//	{
//		ret = g_GetLuaVM()->CallFunction(0, 1);
//	}
//	KLUA_CALL_END(nTopIndex);
//	return ret;
//}

#define LuaSimpleCall1(LuaState,pcsFunc,v0)\
	do{                                 \
		int nTopIndex = 0; \
		KLUA_CALL_BEGIN(&nTopIndex);\
		if(g_GetLuaVM()->PushFunction(pcsFunc)){push(LuaState,v0); g_GetLuaVM()->CallFunction(1,1);} \
		KLUA_CALL_END(nTopIndex); \
	}while(0)

#define LuaSimpleCall2(LuaState,pcsFunc,v0,v1)\
	do{                                  \
		int nTopIndex = 0; \
		KLUA_CALL_BEGIN(&nTopIndex);\
    	if(g_GetLuaVM()->PushFunction(pcsFunc)){push(LuaState,v0);push(LuaState,v1);g_GetLuaVM()->CallFunction(2,1);} \
		KLUA_CALL_END(nTopIndex); \
	}while(0)

#define LuaSimpleCall3(LuaState,pcsFunc,v0,v1,v2)\
	do {                           \
		int nTopIndex = 0; \
		KLUA_CALL_BEGIN(&nTopIndex);\
		if(g_GetLuaVM()->PushFunction(pcsFunc)){push(LuaState,v0);push(LuaState,v1);push(LuaState,v2);g_GetLuaVM()->CallFunction(3,1);} \
		KLUA_CALL_END(nTopIndex); \
	}while(0)


#define LuaSimpleCall4(LuaState,pcsFunc,v0,v1,v2,v3)\
	do { \
		int nTopIndex = 0; \
		KLUA_CALL_BEGIN(&nTopIndex);\
		if(g_GetLuaVM()->PushFunction(pcsFunc)){push(LuaState,v0);push(LuaState,v1);push(LuaState,v2);push(LuaState,v3);g_GetLuaVM()->CallFunction(4,1);} \
		KLUA_CALL_END(nTopIndex); \
	} while(0)

#define LuaSimpleCall5(LuaState,pcsFunc,v0,v1,v2,v3,v4)\
	do { \
		int nTopIndex = 0; \
		KLUA_CALL_BEGIN(&nTopIndex);\
		if(g_GetLuaVM()->PushFunction(pcsFunc)){push(LuaState,v0);push(LuaState,v1);push(LuaState,v2);push(LuaState,v3);push(LuaState,v4);g_GetLuaVM()->CallFunction(5,1);} \
		KLUA_CALL_END(nTopIndex); \
	} while(0)


typedef  int(*pfnOpenLuaLib) (lua_State* tolua_S);
template<typename T> struct LUA_TYPE {};

typedef int LUA_FUNCTION;
typedef int LUA_TABLE;
